/* Parallax PING))) Driver */

#include "EarlTesting.h"
#include "circle_api.h"
#include "ping_driver.h"

/*******************************************************************************
* Function Name  : PingPin
* Description    : Gets a PING))) reading from the pin passed in
*               
*
* Input          : GPIO_TypeDef, GPIO_Pin
* Return         : ping time in usecs.
*******************************************************************************/
u16 PingPin(GPIO_TypeDef* GPIOx, u16 GPIO_Pin )
{
    u32 t1 = 0;
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Set the pin to be an output to send a pulse */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOx, &GPIO_InitStructure);

    // set pin high
    GPIOx->BSRR = GPIO_Pin;

    // wait a couple of us then set pin low
    t1 = getTimeMicro();
    while((getTimeMicro()-t1) <= 2);
    GPIOx->BRR = GPIO_Pin;
    
    /* Set the pin to an input and read the pulse in */
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
    
    
    while((GPIOx->IDR & GPIO_Pin) == (u32)Bit_RESET)
       if(getTimeMicro()-t1 >= PING_TIMEOUT)
        {
            return MAX_PULSE_WIDTH;
        }

    t1 = getTimeMicro();
    while( getTimeMicro() - t1 < 100 );
    
    // wait for pulse to go low
    while((GPIOx->IDR & GPIO_Pin) != (u32)Bit_RESET)
        if(getTimeMicro()-t1 >= PING_TIMEOUT)
        {
            return MAX_PULSE_WIDTH;
        }
    
    // return the time taken to read the pulse in microseconds
    return getTimeMicro()-t1;
}


/*******************************************************************************
* Function Name  : GLOBALS_Init
* Description    : Initializes the global variables to their defaults.
*               
*
* Input          : None
* Return         : None
*******************************************************************************/
u16 convertTimeToCM(u16 usec)
{
    u32 cm = (u32)(usec * 343) / 20000;

    return (u16)cm;
}
